#include "../include/SocketEpoll.h"

namespace ZY {

    void SocketEpoll::_create( int event_number )
    {
        epoll_fd = epoll_create( event_number );
    }

    SocketEpoll::SocketEpoll() : epoll_fd(0)
    {
        //ctor
        _create( LIMIT_CONNECT_NUMBER );
    }

    SocketEpoll::SocketEpoll( int event_number ) : epoll_fd(0)
    {
        _create( event_number );
    }

    void SocketEpoll::setEventNumber( int event_number )
    {
        if ( epoll_fd > 0 ) {
            close( epoll_fd );
        }
        _create( event_number );
    }

    SocketEpoll::~SocketEpoll()
    {
        //dtor
        close( epoll_fd );
    }

    int SocketEpoll::insert( Sock *sock , uint32_t control )
    {
        struct epoll_event ev;

        memset( & ev , 0 , sizeof( ev ) );
        sock->setNonblock();
        ev.data.fd = sock->getFd();
        ev.events = EPOLLET | control;//EPOLLIN|EPOLLOUT|EPOLLHUP|EPOLLERR|EPOLLET;
        return epoll_ctl( epoll_fd ,EPOLL_CTL_ADD, ev.data.fd , &ev );
    }
    int SocketEpoll::remove( Sock *sock )
    {
        return epoll_ctl( epoll_fd ,EPOLL_CTL_DEL, sock->getFd() , NULL );
    }
    int SocketEpoll::update( Sock *sock , uint32_t control )
    {
        struct epoll_event ev;

        memset( & ev , 0 , sizeof( ev ) );
        sock->setNonblock();
        ev.data.fd = sock->getFd();
        ev.events = EPOLLET | control;//EPOLLIN|EPOLLOUT|EPOLLHUP|EPOLLERR|EPOLLET;

        return epoll_ctl( epoll_fd ,EPOLL_CTL_MOD, ev.data.fd , &ev );
    }

    void SocketEpoll::startWait( const int limit_events_number , const int timeout , void (*doFunc)( struct epoll_event *) , void(*eventDone)(void) )
    {
        int i , nfds;
        struct epoll_event events[limit_events_number];

        memset( & events , 0 , sizeof( events) );

        while(1)
        {
            nfds=epoll_wait( epoll_fd ,events, limit_events_number , timeout );

            for(i=0;i<nfds;++i)
            {
                //fcntl( events[i].data.fd , F_SETFL, O_NONBLOCK);
                doFunc( & events[i] );
            }

            if (  eventDone ) {
                eventDone();
            }
        }
    }

}
